
package com.wyzz.hr.bo.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.HttpSession;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.hibernate.FetchMode;
import org.hibernate.criterion.*;

import com.wyzz.hr.base.BaseAction;
import com.wyzz.hr.bo.IAttendshiftBO;
import com.wyzz.hr.bo.IEmployeeBo;
import com.wyzz.hr.dao.IAttendshiftDAO;
import com.wyzz.hr.pojo.Attendperiod;
import com.wyzz.hr.pojo.Attendshift;
import com.wyzz.hr.pojo.Attendshiftareadept;
import com.wyzz.hr.pojo.Department;
import com.wyzz.hr.pojo.Employee;
import com.wyzz.hr.pojo.Empshift;
import com.wyzz.hr.pojo.Location;
import com.wyzz.hr.pojo.Userinfo;
import com.wyzz.hr.spring.SpringBeanFactory;
import com.wyzz.hr.util.Pager;

public class AttendshiftBOImpl implements IAttendshiftBO {

	public AttendshiftBOImpl() {
	}

	public List getObjects(Class clas, String fetch[]) {
		List result = attendshiftDAO.getObjects(clas, fetch);
		return result;
	}

	public Object loadObject(Class obj, Object id, String fetch[],
			boolean cacheable[]) {
		return attendshiftDAO.loadObject(obj, id, fetch, cacheable);
	}

	public boolean updateObject(Object obj) {
		attendshiftDAO.updateObject(obj);
		return true;
	}

	public boolean saveObject(Object obj) {
		attendshiftDAO.saveObject(obj);
		return true;
	}

	public boolean delObject(Object obj) {
		attendshiftDAO.deleteObject(obj);
		return true;
	}

	public boolean saveSchedule(String empid[], Attendshift attdShift,
			Date attdDutyDate1, Date attdDutyDate2, Date defaultDate) {
		HttpSession session = WebContextFactory.get().getSession();
		Userinfo loginuser = (Userinfo) session.getAttribute("userinfo");
		for (int i = 0; i < empid.length; i++) {
			for (Date attdDutyDate = attdDutyDate1; attdDutyDate
					.before(attdDutyDate2)
					|| attdDutyDate.equals(attdDutyDate2); attdDutyDate = nextDate(attdDutyDate)) {
				Empshift empshift = isExist(empid[i], attdDutyDate);
				if (empshift == null
						&& !attdShift.getId().equalsIgnoreCase("0")) {
					empshift = new Empshift();
					empshift.setEmpshiftEmpNo(new Employee(empid[i]));
					empshift.setEmpshiftDate(attdDutyDate);
					empshift.setEmpshiftShiftNo(attdShift);
					empshift.setEmpshiftCreateBy(loginuser.getEmployee()
							.getEmpName());
					empshift.setEmpshiftCreateTime(new Date());
					attendshiftDAO.saveObject(empshift);
					continue;
				}
				if (empshift == null)
					continue;
				if (attdShift.getId().equalsIgnoreCase("0")) {
					attendshiftDAO.deleteObject(empshift);
				} else {
					empshift.setEmpshiftShiftNo(attdShift);
					empshift.setEmpshiftLastChangeBy(loginuser.getEmployee()
							.getEmpName());
					empshift.setEmpshiftLastChangeTime(new Date());
					attendshiftDAO.updateObject(empshift);
				}
			}

		}

		return false;
	}

	public boolean batchUpdateEmpshift(List empshiftList) {
		List toDeleteList = new ArrayList();
		List saveOrUpdateList = new ArrayList();
		for (Iterator i$ = empshiftList.iterator(); i$.hasNext();) {
			Empshift empshift = (Empshift) i$.next();
			if (empshift.getEmpshiftShiftNo() == null)
				toDeleteList.add(empshift);
			else
				saveOrUpdateList.add(empshift);
		}

		if (toDeleteList != null && toDeleteList.size() > 0) {
			StringBuffer deleteIds = new StringBuffer("");
			for (Iterator i$ = toDeleteList.iterator(); i$.hasNext();) {
				Empshift empshift = (Empshift) i$.next();
				deleteIds = deleteIds.append("'").append(empshift.getId())
						.append("',");
			}

			String deleteIdStr = deleteIds.substring(0, deleteIds.length() - 1);
			StringBuffer hql = new StringBuffer("");
			hql = hql.append("delete from Empshift where id in (").append(
					deleteIdStr).append(")");
			attendshiftDAO.exeHql(hql.toString());
		}
		attendshiftDAO.saveOrupdate(saveOrUpdateList);
		return true;
	}

	public String getRealDate(String startDateStr, String endDateStr,
			String dayStr) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date startDate = null;
		Date endDate = null;
		if (Integer.parseInt(dayStr) < 10)
			dayStr = (new StringBuilder()).append("0").append(dayStr)
					.toString();
		Date realDate = null;
		try {
			startDate = format.parse(startDateStr);
			endDate = format.parse(endDateStr);
			realDate = format.parse((new StringBuilder()).append(
					startDateStr.substring(0, 8)).append(dayStr).toString());
			if (realDate.getTime() < startDate.getTime()
					|| endDate.getTime() < realDate.getTime())
				realDate = format.parse((new StringBuilder()).append(
						endDateStr.substring(0, 8)).append(dayStr).toString());
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return format.format(realDate);
	}

	private String addMonth(String yearMonth, int count) {
		String ymArr[] = yearMonth.split("-");
		Calendar calendar = Calendar.getInstance();
		calendar.set(1, Integer.parseInt(ymArr[0]));
		calendar.set(2, Integer.parseInt(ymArr[1]) - 1);
		calendar.add(2, count);
		return (new SimpleDateFormat("yyyy-MM")).format(calendar.getTime());
	}

	private Empshift isExist(String empid, Date attdDutyDate) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Empshift.class);
		detachedCriteria.createAlias("empshiftShiftNo", "shift", 1);
		detachedCriteria.add(Restrictions.eq("empshiftEmpNo.id", empid));
		detachedCriteria.add(Restrictions.eq(Empshift.PROP_EMPSHIFT_DATE,
				attdDutyDate));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		if (result != null && result.size() > 0)
			return (Empshift) result.get(0);
		else
			return null;
	}

	public Boolean isUsed(Attendshift attdShift) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Empshift.class);
		detachedCriteria.add(Restrictions.eq(Empshift.PROP_EMPSHIFT_SHIFT_NO,
				attdShift));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		if (result != null && result.size() > 0)
			return Boolean.valueOf(true);
		else
			return Boolean.valueOf(false);
	}

	public Date nextDate(Date attdDutyDate) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(attdDutyDate);
		calendar.set(5, calendar.get(5) + 1);
		return calendar.getTime();
	}

	public List searchEmployee(Pager page, DetachedCriteria dc) {
		List result = null;
		if (page != null)
			result = attendshiftDAO.findByCriteria(dc, page.getPageSize(), page
					.getCurrentPage());
		else
			result = attendshiftDAO.findByCriteria(dc);
		return result;
	}

	public List searchAttendSchedule(Pager page, DetachedCriteria dc) {
		List result = attendshiftDAO.findByCriteria(dc);
		return result;
	}

	public List searchAttendShift(String attsShortName, Integer status) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		if (attsShortName != null && attsShortName.trim().length() > 0)
			detachedCriteria.add(Restrictions.eq(
					Attendshift.PROP_ATTS_SHORT_NAME, attsShortName.trim()));
		if (status != null)
			detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ATTS_STATUS,
					status));
		detachedCriteria.addOrder(Order.asc(Attendshift.PROP_ATTS_SORT_ID));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		if (result == null || result.size() == 0)
			return null;
		else
			return result;
	}

	public Attendshift getNonStrictDefaultAttendshift() {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ATTS_IS_DEFAULT,
				new Integer(1)));
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ATTS_STRICKED,
				new Integer(0)));
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ATTS_STATUS,
				new Integer(1)));
		List shiftList = attendshiftDAO.findByCriteria(detachedCriteria);
		if (shiftList != null && shiftList.size() > 0)
			return (Attendshift) shiftList.get(0);
		else
			return null;
	}

	public List searchDefaultAttendShiftRela() {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshiftareadept.class);
		detachedCriteria.createAlias("asadShiftId", "shift", 1);
		detachedCriteria.add(Restrictions.eq("shift.attsIsDefault",
				new Integer(1)));
		detachedCriteria.add(Restrictions
				.eq("shift.attsStatus", new Integer(1)));
		detachedCriteria.addOrder(Order.desc("asadAreaId"));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		return result;
	}

	public Attendshift getDefaultAttendshiftByEmp(List relaList,
			Attendshift nonStrictDefaultShift, Employee emp) {
		if (relaList == null || relaList.size() == 0)
			return nonStrictDefaultShift;
		for (Iterator i$ = relaList.iterator(); i$.hasNext();) {
			Attendshiftareadept asad = (Attendshiftareadept) i$.next();
			if (asad.getAsadAreaId() != null
					&& asad.getAsadAreaId().getId().equals(
							emp.getEmpLocationNo().getId()))
				return asad.getAsadShiftId();
			if (asad.getAsadDeptId() != null
					&& asad.getAsadDeptId().getId().equals(
							emp.getEmpDeptNo().getId()))
				return asad.getAsadShiftId();
		}

		return nonStrictDefaultShift;
	}

	public Attendshift getDefaultAttendshiftByEmp(Employee emp) {
		List asadList = searchDefaultAttendShiftRela();
		Attendshift nonStrictDefaultShift = getNonStrictDefaultAttendshift();
		if (asadList == null || asadList.size() == 0)
			return nonStrictDefaultShift;
		for (Iterator i$ = asadList.iterator(); i$.hasNext();) {
			Attendshiftareadept asad = (Attendshiftareadept) i$.next();
			if (asad.getAsadAreaId() != null
					&& emp.getEmpLocationNo() != null
					&& asad.getAsadAreaId().getId().equals(
							emp.getEmpLocationNo().getId()))
				return asad.getAsadShiftId();
			if (asad.getAsadDeptId() != null
					&& emp.getEmpDeptNo() != null
					&& asad.getAsadDeptId().getId().equals(
							emp.getEmpDeptNo().getId()))
				return asad.getAsadShiftId();
		}

		return nonStrictDefaultShift;
	}

	public List searchAttendShiftById(String attsId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ID, attsId));
		detachedCriteria.addOrder(Order.asc(Attendshift.PROP_ATTS_SORT_ID));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		if (result == null || result.size() == 0)
			return null;
		else
			return result;
	}

	public List searchAttendmonthly(Pager page, String emp, Employee employee) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.createAlias("attmEmpId", "emp", 1);
		if (emp != null && emp.trim().length() > 0)
			detachedCriteria.add(Restrictions.or(Restrictions.like(
					"emp.empDistinctNo", emp.trim(), MatchMode.ANYWHERE),
					Restrictions.like("emp.empName", emp.trim(),
							MatchMode.ANYWHERE)));
		if (employee != null && employee.getEmpDeptNo() != null
				&& employee.getEmpDeptNo().getId().trim().length() > 0)
			detachedCriteria.add(Restrictions.eq("emp.empDeptNo", employee
					.getEmpDeptNo()));
		if (employee != null && employee.getEmpLocationNo() != null
				&& employee.getEmpLocationNo().getId().trim().length() > 0)
			detachedCriteria.add(Restrictions.eq("emp.empLocationNo", employee
					.getEmpLocationNo()));
		BaseAction.addOrders(detachedCriteria, page,
				new String[] { (new StringBuilder()).append("emp.").append(
						Employee.PROP_EMP_DISTINCT_NO).toString() });
		page.splitPage(detachedCriteria);
		List result = attendshiftDAO.findByCriteria(detachedCriteria, page
				.getPageSize(), page.getCurrentPage());
		return result;
	}

	public void saveSort(String idArray[]) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.add(Restrictions.in(Attendshift.PROP_ID, idArray));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		Attendshift tmp = null;
		label0: for (int i = 0; i < idArray.length; i++) {
			int j = 0;
			do {
				if (j >= result.size())
					continue label0;
				tmp = (Attendshift) result.get(j);
				if (tmp.getId().equals(idArray[i])) {
					tmp.setAttsSortId(Integer.valueOf(i));
					attendshiftDAO.updateObject(tmp);
					continue label0;
				}
				j++;
			} while (true);
		}

	}

	public void saveDefault(String id, int isDefault) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		int j = 0;
		do {
			if (j >= result.size())
				break;
			Attendshift tmp = (Attendshift) result.get(j);
			if (tmp.getId().equals(id)) {
				tmp.setAttsIsDefault(Integer.valueOf(isDefault));
				attendshiftDAO.updateObject(tmp);
				break;
			}
			j++;
		} while (true);
	}

	public void saveStatus(String id, int status) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		int j = 0;
		do {
			if (j >= result.size())
				break;
			Attendshift tmp = (Attendshift) result.get(j);
			if (tmp.getId().equals(id)) {
				tmp.setAttsStatus(Integer.valueOf(status));
				attendshiftDAO.updateObject(tmp);
				break;
			}
			j++;
		} while (true);
	}

	public int getGlobalDefaultCount() {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ATTS_STRICKED,
				new Integer(0)));
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ATTS_IS_DEFAULT,
				new Integer(1)));
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ATTS_STATUS,
				new Integer(1)));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		if (result != null && result.size() > 0)
			return result.size();
		else
			return 0;
	}

	public IAttendshiftDAO getAttendshiftDAO() {
		return attendshiftDAO;
	}

	public void setAttendshiftDAO(IAttendshiftDAO attendshiftDAO) {
		this.attendshiftDAO = attendshiftDAO;
	}

	public int getMaxSortId() {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.setProjection(Projections.projectionList().add(
				Projections.max("attsSortId")));
		Integer maxId = new Integer(0);
		maxId = (Integer) attendshiftDAO.findByCriteria(detachedCriteria)
				.get(0);
		if (maxId == null)
			return 0;
		else
			return maxId.intValue();
	}

	public boolean isDefault(String attsId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ID, attsId));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		if (result != null && result.size() > 0) {
			Attendshift temp = (Attendshift) result.get(0);
			if (temp != null && temp.getAttsIsDefault() != null
					&& temp.getAttsIsDefault().intValue() == 1)
				return true;
		}
		return false;
	}

	public BigDecimal getShiftHours(String attsId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ID, attsId));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		if (result != null && result.size() > 0) {
			Attendshift temp = (Attendshift) result.get(0);
			return temp.getAttsWorkingHour();
		} else {
			return null;
		}
	}

	public Attendperiod getCurrentPeriod(String yearMonth) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendperiod.class);
		detachedCriteria.add(Restrictions.eq("attpYearmonth", yearMonth));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		Attendperiod period = null;
		if (result != null && result.size() > 0)
			period = (Attendperiod) result.get(0);
		return period;
	}

	public Long getCommenTimes(Date on, Date off, Date start, Date end) {
		long seconds = 0L;
		if (on == null || off == null || start == null || end == null)
			return Long.valueOf(seconds);
		if (end.getTime() < on.getTime() || start.getTime() > off.getTime())
			return Long.valueOf(seconds);
		if (start.getTime() < on.getTime() && off.getTime() < end.getTime()) {
			seconds = (off.getTime() - on.getTime()) / 1000L;
			return Long.valueOf(seconds);
		}
		if (start.getTime() < on.getTime() && on.getTime() < end.getTime()) {
			seconds = (end.getTime() - on.getTime()) / 1000L;
			return Long.valueOf(seconds);
		}
		if (on.getTime() <= start.getTime() && end.getTime() <= off.getTime()) {
			seconds = (end.getTime() - start.getTime()) / 1000L;
			return Long.valueOf(seconds);
		}
		if (start.getTime() < off.getTime() && off.getTime() < end.getTime()) {
			seconds = (off.getTime() - start.getTime()) / 1000L;
			return Long.valueOf(seconds);
		} else {
			return Long.valueOf(seconds);
		}
	}

	public List getAsadListByShift(String shiftId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshiftareadept.class);
		detachedCriteria.setFetchMode("asadShiftId", FetchMode.JOIN);
		detachedCriteria.setFetchMode("asadAreaId", FetchMode.JOIN);
		detachedCriteria.setFetchMode("asadDeptId", FetchMode.JOIN);
		detachedCriteria.add(Restrictions.eq("asadShiftId.id", shiftId));
		return attendshiftDAO.findByCriteria(detachedCriteria);
	}

	public void deleteAsadListByShift(String shiftId) {
		String hql = (new StringBuilder()).append(
				"delete from Attendshiftareadept where asadShiftId = '")
				.append(shiftId).append("'").toString();
		attendshiftDAO.exeHql(hql);
	}

	public String saveOrUpdateShift(Attendshift attdShift, String locIds[],
			String deptIds[]) {
		List asadList = new ArrayList();
		Attendshiftareadept asad = null;
		for (int i = 0; locIds != null && i < locIds.length; i++) {
			asad = new Attendshiftareadept(attdShift, new Location(locIds[i]),
					null);
			asadList.add(asad);
		}

		for (int i = 0; deptIds != null && i < deptIds.length; i++) {
			asad = new Attendshiftareadept(attdShift, null, new Department(
					deptIds[i]));
			asadList.add(asad);
		}

		if (attdShift.getId() == null || attdShift.getId().trim().length() == 0) {
			attdShift.setAttsSortId(Integer.valueOf(getMaxSortId() + 1));
			saveObject(attdShift);
			attendshiftDAO.saveOrupdate(asadList);
		} else {
			updateObject(attdShift);
			deleteAsadListByShift(attdShift.getId());
			attendshiftDAO.saveOrupdate(asadList);
		}
		return "succ";
	}

	public boolean deleteShift(Attendshift attdShift) {
		delObject(attdShift);
		deleteAsadListByShift(attdShift.getId());
		return true;
	}

	public List getShiftIdsByRestrict(String empIds[]) {
		IEmployeeBo empBo = (IEmployeeBo) SpringBeanFactory.getBean("empBo");
		List empList = empBo.searchEmpArray(empIds);
		Employee emp = null;
		Set locIdSet = new HashSet();
		Set deptIdSet = new HashSet();
		for (int i = 0; empList != null && i < empList.size(); i++) {
			emp = (Employee) empList.get(i);
			locIdSet.add(emp.getEmpLocationNo().getId());
			deptIdSet.add(emp.getEmpDeptNo().getId());
		}

		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshiftareadept.class);
		detachedCriteria.add(Restrictions.or(Restrictions.in("asadAreaId.id",
				locIdSet), Restrictions.in("asadDeptId.id", deptIdSet)));
		List relaList = attendshiftDAO.findByCriteria(detachedCriteria);
		Set shiftIdSet = new HashSet();
		for (int i = 0; i < relaList.size(); i++)
			shiftIdSet.add(((Attendshiftareadept) relaList.get(i))
					.getAsadShiftId().getId());

		detachedCriteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Attendshift.class);
		detachedCriteria.add(Restrictions.eq(Attendshift.PROP_ATTS_STATUS,
				new Integer(1)));
		if (shiftIdSet.size() > 0)
			detachedCriteria.add(Restrictions.or(Restrictions.ne(
					Attendshift.PROP_ATTS_STRICKED, new Integer(1)),
					Restrictions.in(Attendshift.PROP_ID, shiftIdSet)));
		else
			detachedCriteria.add(Restrictions.ne(
					Attendshift.PROP_ATTS_STRICKED, new Integer(1)));
		detachedCriteria.addOrder(Order.asc(Attendshift.PROP_ATTS_SORT_ID));
		List result = attendshiftDAO.findByCriteria(detachedCriteria);
		return result;
	}

	private IAttendshiftDAO attendshiftDAO;
}
